
package com.trydofor.id.core;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import com.trydofor.aloe.exception.Exceptions;

/**
 * @author : Shi Rongjiu (www.trydofor.com)
 */
public class ApiExceptions extends Exceptions {
    
    /**
     * default constructor.
     */
    protected ApiExceptions() {
    }
    
    /**
     * <pre>
     * throw TimeoutException if timeout.
     * do nothing if any of,
     *  - timeout is NOT positive.
     *  - unit is null.
     * </pre>
     * 
     * @param startedNano the started nanosecond.
     * @param timeout the timeout.
     * @param unit @Nonnull the time unit of timeout.
     * @throws TimeoutException if timeout
     * @throws NullPointerException if unit is null
     */
    public static void checkTimeoutNano(long startedNano, long timeout, @Nonnull TimeUnit unit)
            throws TimeoutException {
        if (timeout <= 0 || unit == null) return;
        
        long past = unit.convert(System.nanoTime() - startedNano, TimeUnit.NANOSECONDS);
        if (past > timeout) {
            failToCaller(1, new TimeoutException("timeout=" + timeout + ",unit=" + unit + ",past=" + past));
        }
    }
    
    /**
     * throw InterruptedException if the thread is interrupted.
     * 
     * @param t @Nullable the testing thread.
     * @throws InterruptedException if interrupted
     */
    public static void checkThreadInterrupted(@Nullable Thread t) throws InterruptedException {
        if (t == null) return;
        if (t.isInterrupted()) {
            failToCaller(1, new InterruptedException(t.getName() + " is Interrupted"));
        }
    }
    
    /**
     * throw IllegalArgumentException if the range do NOT contains the value.
     * 
     * @param r @Nullable the testing range
     * @param v the testing value.
     * @throws IllegalArgumentException if Not contains.
     */
    public static void checkRangeNotContains(@Nullable Range r, long v) {
        if (r == null) return;
        checkIllegalArgument(!r.contains(v), "para[%s] MUST range %s", v, r);
    }
}
